﻿Type.registerNamespace('ExtJSExtender.Controls');   //注册控件的命名空间 

//定义构造函数
ExtJSExtender.Controls.GridPanelExtenderBehavior = function (element) {
    ExtJSExtender.Controls.GridPanelExtenderBehavior.initializeBase(this, [element]);
}

//属性和方法
ExtJSExtender.Controls.GridPanelExtenderBehavior.prototype = {
    _ExtControl: null,
    _BehaviorState: {},
    _DataStore: {},
    _DataFields: [],
    _Columns: [],
    _TriggerPostBackEvents: null,
    _isPageChangeTriggerDeselect: false,
    _tmpCurrentPageSelectedValues: [],
    //初始化方法
    initialize: function () {
        //调用父类的初始化方法
        ExtJSExtender.Controls.GridPanelExtenderBehavior.callBaseMethod(this, 'initialize');
        var id = this.get_element().id;
        var self = this;

        self._BehaviorState = Ext.decode($('#' + this.get_BehaviorStateHiddenField()).val());
        self._DataStore = Ext.decode($('#' + this.get_DataStoreHiddenField()).val());

        //定义数据模型
        //模型的名字应注意，需要在页面上唯一
        var dataModelId = '_' + id + '_DataModel';
        var dataModelFields = self.get_DataFields();

        //store的配置信息
        var storeCfg = {
            model: dataModelId,
            listeners: {
                'beforeload': Function.createDelegate(self, self.raiseBeforeLoad)
            }
        };
        //分页处理
        if (this.get_Pagination()) {
            storeCfg.pageSize = this.get_PageSize();
        }
        //处理action column，遍历column，查找显示方式
        var columns = this.get_Columns();
        if (columns.length > 0) {
            for (var i = 0; i < columns.length; i++) {
                var column = columns[i];
                switch (column.xtype) {
                    case 'actioncolumn':
                        {
                            if (column.items != null && column.items.length > 0) {
                                for (var j = 0; j < column.items.length; j++) {
                                    var item = column.items[j];
                                    item.handler = Function.createDelegate(self, self.raiseRowCommand);
                                }
                            }
                        }
                        break;
                    default:
                        {

                        }
                        break;
                }
            }
        }

        //异步加载数据的处理
        if (this.get_DataUrl()) {
            storeCfg.proxy = {
                type: 'ajax',
                url: self.get_DataUrl(),
                reader: {
                    type: 'json',
                    root: 'Data',
                    totalProperty: 'TotalCount'
                }
            };
        }

        //grid的配置信息
        var cfg = {
            title: this.get_Title(),
            border: this.get_Border(),
            columns: this.get_Columns(),
            columnLines: true,
            rowLines: true,
            disabled: !self.get_Enabled(),
            listeners: {
                /*'select': function (selectModel, selectedRecord, opts) {
                    var isSelected = true;
                    self.raiseRowSelectChanged.call(self, selectModel, selectedRecord, isSelected, opts);
                },
                'deselect': function (selectModel, selectedRecord, opts) {
                    if (self._isPageChangeTriggerDeselect) {
                        //self._isPageChangeTriggerDeselect = false;
                        return;
                    }
                    var isSelected = false;
                    self.raiseRowSelectChanged.call(self, selectModel, selectedRecord, isSelected, opts);
                }*/
                'selectionchange': function (selectModel, selectedRecords, opts) {
                    if (self._isPageChangeTriggerDeselect) {    //如果是因为翻页而触发的数据选择改变，则不处理
                        return;
                    }
                    self.raiseRowSelectChanged.call(self, selectModel, selectedRecords, opts);
                }
            },
            viewConfig: {
                listeners: {
                    refresh: function () {
                        //设置控件滚动条的位置
                        var queryEl = $(this.el.dom);
                        if (self._BehaviorState.NeedResetScroll < 2) {     //refresh事件在一次创建中执行两次，一次是创建，一次是加载数据
                            if (self._BehaviorState.ScrollX > 0) queryEl.scrollLeft(self._BehaviorState.ScrollX);
                            if (self._BehaviorState.ScrollY > 0) queryEl.scrollTop(self._BehaviorState.ScrollY);
                            self._BehaviorState.NeedResetScroll++;
                        }

                        //添加滚动条事件
                        queryEl.unbind('scroll').scroll(function () {
                            self._BehaviorState.ScrollX = event.srcElement.scrollLeft;
                            self._BehaviorState.ScrollY = event.srcElement.scrollTop;
                            self.storeBehaviorState();
                        });
                    }
                }
            },
            renderTo: id
        };
        if (this.get_Height()) cfg.height = this.get_Height();
        if (this.get_Width()) cfg.width = this.get_Width();

        //调用Ext的方法，完成控件的绘制
        Ext.onReady(function () {
            Ext.define(dataModelId, {
                extend: 'Ext.data.Model',
                fields: dataModelFields
            });

            //store
            var store = Ext.create('Ext.data.Store', storeCfg);
            cfg.store = store;

            //pagination
            if (self.get_Pagination()) {
                //paging toolbar
                cfg.bbar = Ext.create('Ext.PagingToolbar', {
                    store: store,
                    listeners: {
                        'beforechange': function () {
                            self._isPageChangeTriggerDeselect = true;
                        },
                        'change': function () {
                            self._isPageChangeTriggerDeselect = false;
                        }
                    },
                    displayInfo: true,
                    displayMsg: '共{2}行,当前显示：{0}-{1}',
                    emptyMsg: "没有数据"
                });
            }
            //row number
            if (self.get_ShowRowNumberColumn()) {
                cfg.columns.splice(0, 0, {
                    xtype: 'rownumberer',
                    width: 40,
                    resizable: true,
                    sortable: false
                });
            }
            //selection
            if (self.get_ShowSelectionColumn()) {
                cfg.selModel = Ext.create('Ext.selection.CheckboxModel', {
                    checkOnly: true,    //只有单击checkbox才能够选中行，默认为单击行就能选中
                    injectCheckbox: self.get_ShowRowNumberColumn() ? 1 : 0,    //插入checkbox 列的位置，默认为0
                    mode: self.get_SelectionMode().toUpperCase(),  //SINGLE 单选 MULTI 多选（可以使用CTRL和SHIFT） SIMPLE 简单选择（多选，需要单击每一行来选中）
                    showHeaderCheckbox: self.get_SelectionMode().toUpperCase() != 'SINGLE' //在列头显示checkbox，默认为true
                });
            }
            else {
                cfg.selModel = Ext.create('Ext.selection.RowModel', {
                    mode: self.get_SelectionMode().toUpperCase()  //SINGLE 单选 MULTI 多选（可以使用CTRL和SHIFT） SIMPLE 简单选择（多选，需要单击每一行来选中）
                });
            }

            //Enable Edit
            if (self.get_EnableEdit()) {
                cfg.plugins = [
                    Ext.create('Ext.grid.plugin.CellEditing', {
                        // 触发进入编辑状态的事件
                        triggerEvent: self.get_EditTriggerEvent()
                    })
                ];
            }

            this._ExtControl = Ext.create('Ext.grid.Panel', cfg);
            if (self.get_EnableEdit()) {
                //添加编辑事件
                this._ExtControl.on('edit', function (editor, e) {
                    /*
                        e : Object
                        An edit event with the following properties:

                        grid - The grid
                        record - The record that was edited
                        field - The field name that was edited
                        value - The value being set
                        originalValue - The original value for the field, before the edit.
                        row - The grid table row
                        column - The grid Column defining the column that was edited.
                        rowIdx - The row index that was edited
                        colIdx - The column index that was edited
                    */
                    //提交数据，去掉左上角的小箭头
                    e.record.commit();

                    //保存编辑后的数据到隐藏域中
                    self.exchangeToDataStore(store);
                    self.storeDataStore();
                });
            }

            //为Store添加事件处理
            store.on('datachanged', function (theStore, opts) {
                //持久化当前页的数据
                var data = self.exchangeToDataStore(theStore);
                self.storeDataStore();

                var keyField = self.get_KeyField();
                if (!keyField) return;

                //重新选中已选择的数据
                //并且要将当前也选中的数据主键保存在临时列表中
                if (self._BehaviorState.AllSelectedValues != null && self._BehaviorState.AllSelectedValues.length > 0) {
                    self._tmpCurrentPageSelectedValues = [];
                    if (!data) return;

                    $.each(self._BehaviorState.AllSelectedValues, function (index, value) { //遍历所有选中的数据
                        /*for (var i = 0; i < store.data.items.length; i++) {
                            if (store.data.items[i].raw)
                                //this._DataStore.Data[i] = $.extend(store.data.items[i].raw, store.data.items[i].data);
                            else
                                //this._DataStore.Data[i] = store.data.items[i].data;
                        }*/
                        for (var i = 0; i < data.Data.length; i++) {
                            var keyValue = data.Data[i][keyField];
                            if (keyValue == value) {
                                self._tmpCurrentPageSelectedValues.push(keyValue);
                                self._ExtControl.selModel.select(i, true, true);
                            }
                        }
                    });
                }
                //self._ExtControl.selModel.select();
            }, self);

            if (this._DataStore && this._DataStore.Data && this._DataStore.Data.length > 0) {
                //store.currentPage = this._DataStore.CurrentPage;
                //store.loadRawData(this._DataStore);

                store.currentPage = this._DataStore.CurrentPage;
                var result = store.proxy.reader.read(this._DataStore);
                if (result.success) {
                    store.totalCount = result.total;
                    store.loadRecords(result.records, { 'addRecords': false, 'start': (store.currentPage - 1) * store.pageSize });
                    store.fireEvent('load', store, result.records, true);
                }


                //store.totalCount = result.total;
                //store.loadRecords(result.records, { 'addRecords': false, 'start': this._DataStore.FromRecord });
                //store.fireEvent('load', store, result.records, true);
            }
            else {
                store.loadPage(1);
            }
        }, this);
    },
    dispose: function () {
        ExtJSExtender.Controls.GridPanelExtenderBehavior.callBaseMethod(this, 'dispose');
    },
    get_DataFields: function () {
        return this._DataFields;
    },
    set_DataFeilds: function () {
        this._DataFields = value;
    },
    get_Title: function () {
        return this._Title;
    },
    set_Title: function (value) {
        this._Title = value;
    },
    get_Enabled: function () {
        return this._Enabled;
    },
    set_Enabled: function (value) {
        this._Enabled = value;
    },
    get_Width: function () {
        return this._Width;
    },
    set_Width: function (value) {
        this._Width = value;
    },
    get_Height: function () {
        return this._Height;
    },
    set_Height: function (value) {
        this._Height = value;
    },
    get_Border: function () {
        return this._Border;
    },
    set_Border: function (value) {
        this._Border = value;
    },
    get_UniqueID: function () {
        return this._UniqueID;
    },
    set_UniqueID: function (value) {
        this._UniqueID = value;
    },
    get_DataUrl: function () {
        return this._DataUrl;
    },
    set_DataUrl: function (value) {
        this._DataUrl = value;
    },
    get_PageSize: function () {
        return this._PageSize;
    },
    set_PageSize: function (value) {
        this._PageSize = value;
    },
    get_Pagination: function () {
        return this._Pagination;
    },
    set_Pagination: function (value) {
        this._Pagination = value;
    },
    get_EnableEdit: function () {
        return this._EnableEdit;
    },
    set_EnableEdit: function (value) {
        this._EnableEdit = value;
    },
    get_EditTriggerEvent: function () {
        return this._EditTriggerEvent;
    },
    set_EditTriggerEvent: function (value) {
        this._EditTriggerEvent = value;
    },
    get_Columns: function () {
        return this._Columns;
    },
    set_Columns: function (value) {
        this._Columns = Ext.decode(value);
    },
    get_AutoPostBack: function () {
        return this._AutoPostBack;
    },
    set_AutoPostBack: function (value) {
        this._AutoPostBack = value;
    },
    get_ShowRowNumberColumn: function () {
        return this._ShowRowNumberColumn;
    },
    set_ShowRowNumberColumn: function (value) {
        this._ShowRowNumberColumn = value;
    },
    get_ShowSelectionColumn: function () {
        return this._ShowSelectionColumn;
    },
    set_ShowSelectionColumn: function (value) {
        this._ShowSelectionColumn = value;
    },
    get_SelectionMode: function () {
        return this._SelectionMode;
    },
    set_SelectionMode: function (value) {
        this._SelectionMode = value;
    },
    get_BehaviorStateHiddenField: function () {
        return this._BehaviorStateHiddenField;
    },
    set_BehaviorStateHiddenField: function (value) {
        this._BehaviorStateHiddenField = value;
    },
    get_DataStoreHiddenField: function () {
        return this._DataStoreHiddenField;
    },
    set_DataStoreHiddenField: function (value) {
        this._DataStoreHiddenField = value;
    },
    get_TriggerPostBackEvents: function () {
        return this._TriggerPostBackEvents;
    },
    set_TriggerPostBackEvents: function (value) {
        this._TriggerPostBackEvents = value;
    },
    get_KeyField: function () {
        return this._KeyField;
    },
    set_KeyField: function (value) {
        this._KeyField = value;
    },
    storeBehaviorState: function () {
        $('#' + this.get_BehaviorStateHiddenField()).val(Ext.encode(this._BehaviorState));
    },
    storeDataStore: function () {
        $('#' + this.get_DataStoreHiddenField()).val(Ext.encode(this._DataStore));
    },
    exchangeToDataStore: function (store) {
        this._DataStore.CurrentPage = store.currentPage;
        this._DataStore.TotalCount = store.totalCount;
        //this._DataStore.PageSize = this.get_PageSize();
        //this._DataStore.DataUrl = this.get_DataUrl();
        this._DataStore.Data = [];

        for (var i = 0; i < store.data.items.length; i++) {
            if (store.data.items[i].raw)
                this._DataStore.Data[i] = $.extend(store.data.items[i].raw, store.data.items[i].data);
            else
                this._DataStore.Data[i] = store.data.items[i].data;
        }

        return this._DataStore;
    },
    raiseRowCommand: function (grid, rowIndex, colIndex, actionConfig, eventObject, record, dom) {
        if (this._TriggerPostBackEvents.RowCommand) {
            var arguments = {
                'ActionName': actionConfig.ActionName,
                'RowIndex': rowIndex,
                'ColumnIndex': colIndex,
                'RowData': $.extend(record.data, record.raw)
            };

            this.invoke(ExtJSExtender.Util.serializeEventArgs("RowCommand", arguments), null, null, null, true);
        }
    },
    raiseRowSelectChanged: function (selectModel, selectedRecords, opts) {
        var self = this;
        var keyField = self.get_KeyField();
        if (!keyField) { alert('未设置主键字段，无法获取选中行的主键数据！'); return; }

        var otherPageSelectedValues = $.grep(self._BehaviorState.AllSelectedValues, function (value, index) {
            return $.inArray(value, self._tmpCurrentPageSelectedValues) != -1;
        }, true);

        self._tmpCurrentPageSelectedValues = $.map(selectedRecords, function (record) {
            var recordData = $.extend(record.data, record.raw);
            var keyValue = recordData[keyField];

            return keyValue;
        });

        self._BehaviorState.AllSelectedValues = $.merge(otherPageSelectedValues, self._tmpCurrentPageSelectedValues);
        self._BehaviorState.AllSelectedValues = $.unique(self._BehaviorState.AllSelectedValues);
        self.storeBehaviorState();

        /*
        //处理选中的数据
        for (var i = 0; i < selectedRecords.length; i++) {
            var record = selectedRecords[i];
            var keyValue = record[keyField];
            if (isSelected) {   //将选中的记录持久化
                if ($.inArray(keyValue, self._BehaviorState.AllSelectedValues) > -1) {
                    self._BehaviorState.AllSelectedValues.push(keyValue);
                }
            }
            else {      //将取消选中的记录从持久化中删除
                self._BehaviorState.AllSelectedValues = $.grep(self._BehaviorState.AllSelectedValues, function (value, index) {
                    return value == keyValue;
                }, true);
            }
        }*/


        /*
        var record = selectedRecord;
        var recordData = $.extend(record.data, record.raw);
        var keyValue = recordData[keyField];
        if (isSelected) {   //将选中的记录持久化
            if ($.inArray(keyValue, self._BehaviorState.AllSelectedValues) == -1) { //等于-1为不存在
                self._BehaviorState.AllSelectedValues.push(keyValue);
            }
        }
        else {      //将取消选中的记录从持久化中删除
            self._BehaviorState.AllSelectedValues = $.grep(self._BehaviorState.AllSelectedValues, function (value, index) {
                return value == keyValue;
            }, true);
        }*/
        //this.storeBehaviorState();

        if (this._TriggerPostBackEvents.RowSelectChanged) {
            var arguments = {
                'CurrentPageSelectedValues': self._tmpCurrentPageSelectedValues
            };
            this.invoke(ExtJSExtender.Util.serializeEventArgs("RowSelectChanged", arguments), null, null, null, true);
        }
    },
    raiseBeforeLoad: function (store, operation, opts) {
        var self = this;
        if (this._TriggerPostBackEvents.LoadPageData) {
            var arguments = {
                'PageSize': operation.limit,
                'CurrentPage': operation.page
            };
            /*
            Ext.defer(function () {
                self.invoke(ExtJSExtender.Util.serializeEventArgs("LoadPageData", this), null, null, null, true);
            }, 1, arguments);
            */
            self.invoke(ExtJSExtender.Util.serializeEventArgs("LoadPageData", arguments), null, null, null, true);
            return false;
        }
    },
    invoke: function (args, onComplete$delegate, context, onError$delegate, async) {
        var callbackId = this.get_UniqueID();
        if (this._AutoPostBack) {
            __doPostBack(callbackId, args);
        }
        else {
            //WebForm_DoCallback(callbackId, args, onComplete$delegate, context, onError$delegate, async);
        }
    }
}

ExtJSExtender.Controls.GridPanelExtenderBehavior.registerClass('ExtJSExtender.Controls.GridPanelExtenderBehavior', Sys.UI.Control);
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();